#include "stdafx.h"
#include "xKernel/IxNode.h"
#include "xKernel/IxView.h"
#include "LayoutHorizon.h"

CxLayoutHorizon::CxLayoutHorizon()
{}

CxLayoutHorizon::~CxLayoutHorizon()
{}


HRESULT CxLayoutHorizon::Layout(IxView* pView)
{
    CComQIPtr<IxNode> spNode = pView;
    if (!pView || !spNode)
    {
        return E_INVALIDARG;
    }

    CRect rcPadding(0, 0, 0, 0);
    pView->GetPadding(&rcPadding);

    CRect rcBox(0, 0, 0, 0);
    pView->GetBoxRect(&rcBox);

    CComPtr<IxNode> spChildNode;
    CComQIPtr<IxView> spChildView;

    INT nLeft   = rcPadding.left;
    INT nRight  = rcBox.Width() - rcPadding.right;

    if (nRight < nLeft)
        nRight = nLeft;

    const INT nTop    = rcPadding.top;
    const INT nBottom = ((rcBox.Height() - rcPadding.bottom) > nTop) ? (rcBox.Height() - rcPadding.bottom) : nTop;

    CSize   szChild(0, 0);
    CRect   rcChildMargin(0,0,0,0);
    INT     nAlignment = E_ALIGNMENT_LEFT | E_ALIGNMENT_TOP;

    INT nCount = 0;
    spNode->GetChildrenCount(&nCount);
    for (INT i = 0; i < nCount; ++i)
    {
        spChildNode = NULL;
        spNode->GetChildByIndex(i, &spChildNode);
        spChildView = spChildNode;
        if (spChildNode && spChildView)
        {
            spChildView->GetMargin(&rcChildMargin);
            spChildView->GetAlignment(&nAlignment);
            spChildView->GetSize(&szChild);

            INT xPos = 0;

            if (nAlignment & E_ALIGNMENT_RIGHT)
            {
                xPos = nRight - rcChildMargin.right - szChild.cx;
                nRight = xPos - rcChildMargin.left;
            }
            else if (nAlignment & E_ALIGNMENT_H_CENTER)
            {
                xPos = (rcBox.Height() - rcPadding.top - rcPadding.bottom - szChild.cx) >> 1;
            }
            else    // E_ALIGNMENT_LEFT
            {
                xPos = nLeft + rcChildMargin.left;
                nLeft = xPos + szChild.cx + rcChildMargin.right;
            }

            INT yPos = 0;

            if (nAlignment & E_ALIGNMENT_BOTTOM)
            {
                yPos = nBottom - szChild.cy - rcChildMargin.bottom;
            }
            else if (nAlignment & E_ALIGNMENT_V_CENTER)
            {
                yPos = (nBottom - nTop - szChild.cy) >> 1;
            }
            else    // E_ALIGNMENT_TOP
            {
                yPos = nTop + rcChildMargin.top;
            }

            spChildView->SetPosition(CPoint(xPos, yPos));
        }
    }

    return S_OK;
}